Preparations

knitr::opts_knit$set(root.dir = rprojroot::find_rstudio_root_file(), 
                     fig.width=14,
                     fig.height=14)
set.seed(42)
library(tidyverse)

Read data

tx_gene_meta <- read_csv("./data/mm_ens97_metadata.txt")
tx_gene_meta

Gene Level

Extract Gene metadata

gene_meta <- 
  tx_gene_meta %>%
         dplyr::group_by(gene_id) %>%
         dplyr::slice(1) %>%
  ungroup() %>%
  select(gene_name, gene_len, perc_gene_gc, gene_id, seqnames, gene_biotype, gene_id_version)
gene_meta

Some gene names are not unique

duplicated_gene_names <-
  gene_meta %>%
  dplyr::filter( duplicated(gene_name ))%>%
  pull(gene_name) %>%
  unique()
length(duplicated_gene_names)
[1] 110
gene_meta %>%
  dplyr::filter(gene_name%in% duplicated_gene_names ) %>%
  arrange(gene_name)

Gene Biotypes

biotype_count <-
  gene_meta %>% 
  group_by(gene_biotype) %>% 
  tally(sort = TRUE)
biotype_count
biotype_targets <-
  biotype_count %>%
  slice(1:10)%>% 
  pull(gene_biotype)

Percentage of Gene GC Content

ggplot(gene_meta %>%
         filter(gene_biotype %in% biotype_targets),
       aes(perc_gene_gc)) +
  geom_histogram(bins = 150)   +
  facet_wrap(~gene_biotype)

ggplot(gene_meta %>%
         filter(gene_biotype %in% biotype_targets) ,
       aes(gene_len)) +
  geom_histogram(bins = 150)  +  
   scale_x_log10() +
  facet_wrap(~gene_biotype)

ggplot(gene_meta %>%
         filter(gene_biotype %in% biotype_targets), 
       aes(perc_gene_gc, gene_len))+
  geom_point(size=0.8,
              alpha=0.7) +
  geom_density_2d() +  
   scale_y_log10() +
   theme(legend.position="none") +
  facet_wrap(~gene_biotype)

Transcript Level

Transcript Biotypes

tx_biotype_count <-
  tx_gene_meta %>% 
  group_by(tx_biotype) %>% 
  tally(sort = TRUE)
tx_biotype_count
tx_biotype_targets <-
  tx_biotype_count %>%
  slice(1:8)%>% 
  pull(tx_biotype)

Exonic vs intronic lengths

ggplot(tx_gene_meta %>%
         filter(tx_biotype %in% tx_biotype_targets)) +
  geom_point( aes(exonic_len, intronic_len, colour=perc_gene_gc),
              size=0.3,
              alpha=0.6)  +  
  scale_x_log10() +
   scale_y_log10() +
  facet_wrap(~tx_biotype) +
  scale_colour_gradient2(midpoint=10, mid = "yellow")

Exonic vs intronic counts

ggplot(tx_gene_meta %>%
         filter(tx_biotype %in% tx_biotype_targets)) +
  geom_point( aes(nexon, nintron, colour=gene_len),
              size=0.8,
              alpha=0.7)  +  
  scale_x_log10() +
   scale_y_log10()  +
  facet_wrap(~tx_biotype) 

Pre-mRNA vs Exonic lengths

ggplot(tx_gene_meta %>%
         filter(tx_biotype %in% tx_biotype_targets & nexon!=1),
       aes( premrna_len, exonic_len, colour=nexon)) +
  geom_point( size=0.1,
              alpha=0.3)  +    
  geom_density_2d() +  
  scale_x_log10() +
   scale_y_log10() +
  facet_wrap(~tx_biotype) 

Exonic Counts vs Exonic lengths

ggplot(tx_gene_meta %>%
         filter(tx_biotype %in% tx_biotype_targets ),
       aes( nexon, exonic_len, colour=premrna_len)) +
  geom_point( size=0.1,
              alpha=0.3)  +    
  scale_x_log10() +
   scale_y_log10() +
  facet_wrap(~tx_biotype) 

Number of transcipts by gene

count_tx_by_gene <-
  tx_gene_meta %>%
  count(gene_id,gene_name, gene_biotype) %>%
  arrange(-n)
count_tx_by_gene 
ggplot(count_tx_by_gene, aes(n)) +
  geom_histogram(bins = 100)  

top_genes <- 
  count_tx_by_gene %>%
  slice(1:20) %>%
  pull(gene_name)
top_genes
 [1] "Rian"          "Tcf4"          "Gm29154"       "3110039I08Rik" "Ank3"          "Smarca2"       "Pcdh15"        "Crem"          "Kcnma1"        "Hand2os1"     
[11] "Sorbs2"        "Wdr45"         "Nedd4l"        "Adgrl3"        "Ttc3"          "Hnrnpk"        "Qars"          "U2af1l4"       "Anks1b"        "Arhgef2"      
ggplot(tx_gene_meta %>% 
         dplyr::filter(gene_name%in% top_genes))+
  geom_point( aes(exonic_len, intronic_len, colour=nexon >=10)) +
  facet_wrap(gene_biotype~gene_name,   scales = "free")

tx_10_genes <- 
  count_tx_by_gene %>%
  filter(n==10) %>%
  slice(1:20) %>%
  pull(gene_name)
ggplot(tx_gene_meta %>% 
         dplyr::filter(gene_name%in% tx_10_genes))+
  geom_point( aes(exonic_len, intronic_len, colour=nexon >=10)) +
  facet_wrap(~gene_name,  scales = "free") 

NA
single_transcript_genes <-
  count_tx_by_gene %>% 
  dplyr::filter(n==1) %>% 
  pull(gene_name)
length(single_transcript_genes)
[1] 34389
ggplot(tx_gene_meta  %>% 
         dplyr::filter(gene_name%in% single_transcript_genes & gene_biotype %in% biotype_targets ))+
  geom_point( aes(exonic_len, intronic_len,  colour=perc_gene_gc),
              size=0.2,
              alpha=0.5)  +  
  scale_x_log10() +
   scale_y_log10() +
  facet_wrap(~tx_biotype)  +
  scale_colour_gradient2(midpoint=10, mid = "yellow")

Single exon transcripts

  tx_gene_meta %>%
  count(nexon ) %>%
  arrange(-n)
ggplot(tx_gene_meta %>% 
         dplyr::filter(tx_biotype %in% tx_biotype_targets & nexon== 2)) +
  geom_point( aes(exonic_len, intronic_len,  colour=perc_gene_gc),
              size=0.2,
              alpha=0.5)  +  
  scale_x_log10() +
   scale_y_log10() +
  facet_wrap(~tx_biotype)  +
  scale_colour_gradient2(midpoint=10, mid = "yellow")

ggplot(tx_gene_meta %>% 
         dplyr::filter(tx_biotype %in% tx_biotype_targets & nexon< 10 & nexon> 1)) +
  geom_point( aes(exonic_len, intronic_len,  colour=perc_gene_gc),
              size=0.2,
              alpha=0.5)  +  
  scale_x_log10() +
   scale_y_log10() +
  facet_wrap(~tx_biotype)  +
  scale_colour_gradient2(midpoint=10, mid = "yellow")

ggplot(tx_gene_meta %>% 
         dplyr::filter(tx_biotype %in% tx_biotype_targets & nexon>= 10)) +
  geom_point( aes(exonic_len, intronic_len,  colour=perc_gene_gc),
              size=0.2,
              alpha=0.5)  +  
  scale_x_log10() +
   scale_y_log10() +
  facet_wrap(~tx_biotype)  +
  scale_colour_gradient2(midpoint=10, mid = "yellow")

sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.3 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.7.1
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.7.1

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] forcats_0.4.0   stringr_1.4.0   dplyr_0.8.3     purrr_0.3.2     readr_1.3.1     tidyr_0.8.3     tibble_2.1.3    ggplot2_3.2.1   tidyverse_1.2.1

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.2       cellranger_1.1.0 pillar_1.4.2     compiler_3.6.1   tools_3.6.1      digest_0.6.20    zeallot_0.1.0    lubridate_1.7.4  jsonlite_1.6    
[10] nlme_3.1-140     gtable_0.3.0     lattice_0.20-38  pkgconfig_2.0.2  rlang_0.4.0      cli_1.1.0        rstudioapi_0.10  haven_2.1.1      xfun_0.8        
[19] withr_2.1.2      xml2_1.2.2       httr_1.4.1       knitr_1.24       generics_0.0.2   vctrs_0.2.0      hms_0.5.0        rprojroot_1.3-2  grid_3.6.1      
[28] tidyselect_0.2.5 glue_1.3.1       R6_2.4.0         readxl_1.3.1     modelr_0.1.5     magrittr_1.5     MASS_7.3-51.4    backports_1.1.4  scales_1.0.0    
[37] rvest_0.3.4      assertthat_0.2.1 colorspace_1.4-1 labeling_0.3     stringi_1.4.3    lazyeval_0.2.2   munsell_0.5.0    broom_0.5.2      crayon_1.3.4    
LS0tCnRpdGxlOiAiRXhwbG9yZSBtb3VzZSBtZXRhZGF0YSIKYXV0aG9yOiAKLSBuYW1lOiBSaWNrIEZhcm91bmkKICBhZmZpbGlhdGlvbjoKICAtICZjcnVrIERlcGFydG1lbnQgb2YgSHVtYW4gR2VuZXRpY3MsIE1jR2lsbCBVbml2ZXJzaXR5LCAgTW9udHJlYWwsIENhbmFkYQpkYXRlOiAnYHIgZm9ybWF0KFN5cy5EYXRlKCksICIlWS0lQi0lZCIpYCcKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCiMgUHJlcGFyYXRpb25zCgpgYGB7ciBzZXR1cH0Ka25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBycHJvanJvb3Q6OmZpbmRfcnN0dWRpb19yb290X2ZpbGUoKSwgCiAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aD0xNCwKICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodD0xNCkKc2V0LnNlZWQoNDIpCmBgYAoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpgYGAKCgojIyBSZWFkIGRhdGEKCgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KdHhfZ2VuZV9tZXRhIDwtIHJlYWRfY3N2KCIuL2RhdGEvbW1fZW5zOTdfbWV0YWRhdGEudHh0IikKdHhfZ2VuZV9tZXRhCmBgYAoKIyBHZW5lIExldmVsIAoKIyMgRXh0cmFjdCBHZW5lIG1ldGFkYXRhCgpgYGB7cn0KZ2VuZV9tZXRhIDwtIAogIHR4X2dlbmVfbWV0YSAlPiUKICAgICAgICAgZHBseXI6Omdyb3VwX2J5KGdlbmVfaWQpICU+JQogICAgICAgICBkcGx5cjo6c2xpY2UoMSkgJT4lCiAgdW5ncm91cCgpICU+JQogIHNlbGVjdChnZW5lX25hbWUsIGdlbmVfbGVuLCBwZXJjX2dlbmVfZ2MsIGdlbmVfaWQsIHNlcW5hbWVzLCBnZW5lX2Jpb3R5cGUsIGdlbmVfaWRfdmVyc2lvbikKZ2VuZV9tZXRhCmBgYAoKClNvbWUgZ2VuZSBuYW1lcyBhcmUgbm90IHVuaXF1ZQoKYGBge3J9CmR1cGxpY2F0ZWRfZ2VuZV9uYW1lcyA8LQogIGdlbmVfbWV0YSAlPiUKICBkcGx5cjo6ZmlsdGVyKCBkdXBsaWNhdGVkKGdlbmVfbmFtZSApKSU+JQogIHB1bGwoZ2VuZV9uYW1lKSAlPiUKICB1bmlxdWUoKQpsZW5ndGgoZHVwbGljYXRlZF9nZW5lX25hbWVzKQpgYGAKCmBgYHtyfQpnZW5lX21ldGEgJT4lCiAgZHBseXI6OmZpbHRlcihnZW5lX25hbWUlaW4lIGR1cGxpY2F0ZWRfZ2VuZV9uYW1lcyApICU+JQogIGFycmFuZ2UoZ2VuZV9uYW1lKQpgYGAKCgojIyMgR2VuZSBCaW90eXBlcwoKCmBgYHtyfQpiaW90eXBlX2NvdW50IDwtCiAgZ2VuZV9tZXRhICU+JSAKICBncm91cF9ieShnZW5lX2Jpb3R5cGUpICU+JSAKICB0YWxseShzb3J0ID0gVFJVRSkKYmlvdHlwZV9jb3VudApgYGAKCmBgYHtyfQpiaW90eXBlX3RhcmdldHMgPC0KICBiaW90eXBlX2NvdW50ICU+JQogIHNsaWNlKDE6MTApJT4lIAogIHB1bGwoZ2VuZV9iaW90eXBlKQpgYGAKCgoKIyMjIFBlcmNlbnRhZ2Ugb2YgR2VuZSBHQyBDb250ZW50CgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEyfQpnZ3Bsb3QoZ2VuZV9tZXRhICU+JQogICAgICAgICBmaWx0ZXIoZ2VuZV9iaW90eXBlICVpbiUgYmlvdHlwZV90YXJnZXRzKSwKICAgICAgIGFlcyhwZXJjX2dlbmVfZ2MpKSArCiAgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDE1MCkgICArCiAgZmFjZXRfd3JhcCh+Z2VuZV9iaW90eXBlKQpgYGAKCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTJ9CmdncGxvdChnZW5lX21ldGEgJT4lCiAgICAgICAgIGZpbHRlcihnZW5lX2Jpb3R5cGUgJWluJSBiaW90eXBlX3RhcmdldHMpICwKICAgICAgIGFlcyhnZW5lX2xlbikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTUwKSAgKyAgCiAgIHNjYWxlX3hfbG9nMTAoKSArCiAgZmFjZXRfd3JhcCh+Z2VuZV9iaW90eXBlKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MjB9CmdncGxvdChnZW5lX21ldGEgJT4lCiAgICAgICAgIGZpbHRlcihnZW5lX2Jpb3R5cGUgJWluJSBiaW90eXBlX3RhcmdldHMpLCAKICAgICAgIGFlcyhwZXJjX2dlbmVfZ2MsIGdlbmVfbGVuKSkrCiAgZ2VvbV9wb2ludChzaXplPTAuOCwKICAgICAgICAgICAgICBhbHBoYT0wLjcpICsKICBnZW9tX2RlbnNpdHlfMmQoKSArICAKICAgc2NhbGVfeV9sb2cxMCgpICsKICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGZhY2V0X3dyYXAofmdlbmVfYmlvdHlwZSkKYGBgCgoKCiMgVHJhbnNjcmlwdCBMZXZlbCAKCiMjIyBUcmFuc2NyaXB0IEJpb3R5cGVzCgoKYGBge3J9CnR4X2Jpb3R5cGVfY291bnQgPC0KICB0eF9nZW5lX21ldGEgJT4lIAogIGdyb3VwX2J5KHR4X2Jpb3R5cGUpICU+JSAKICB0YWxseShzb3J0ID0gVFJVRSkKdHhfYmlvdHlwZV9jb3VudApgYGAKCmBgYHtyfQp0eF9iaW90eXBlX3RhcmdldHMgPC0KICB0eF9iaW90eXBlX2NvdW50ICU+JQogIHNsaWNlKDE6OCklPiUgCiAgcHVsbCh0eF9iaW90eXBlKQpgYGAKCiMjIEV4b25pYyB2cyBpbnRyb25pYyBsZW5ndGhzCgpgYGB7ciwgZmlnLndpZHRoPTE2fQpnZ3Bsb3QodHhfZ2VuZV9tZXRhICU+JQogICAgICAgICBmaWx0ZXIodHhfYmlvdHlwZSAlaW4lIHR4X2Jpb3R5cGVfdGFyZ2V0cykpICsKICBnZW9tX3BvaW50KCBhZXMoZXhvbmljX2xlbiwgaW50cm9uaWNfbGVuLCBjb2xvdXI9cGVyY19nZW5lX2djKSwKICAgICAgICAgICAgICBzaXplPTAuMywKICAgICAgICAgICAgICBhbHBoYT0wLjYpICArICAKICBzY2FsZV94X2xvZzEwKCkgKwogICBzY2FsZV95X2xvZzEwKCkgKwogIGZhY2V0X3dyYXAofnR4X2Jpb3R5cGUpICsKICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKG1pZHBvaW50PTEwLCBtaWQgPSAieWVsbG93IikKCmBgYAoKCgoKCgoKCiMjIEV4b25pYyB2cyBpbnRyb25pYyBjb3VudHMKCgpgYGB7ciwgZmlnLndpZHRoPTIwfQpnZ3Bsb3QodHhfZ2VuZV9tZXRhICU+JQogICAgICAgICBmaWx0ZXIodHhfYmlvdHlwZSAlaW4lIHR4X2Jpb3R5cGVfdGFyZ2V0cykpICsKICBnZW9tX3BvaW50KCBhZXMobmV4b24sIG5pbnRyb24sIGNvbG91cj1nZW5lX2xlbiksCiAgICAgICAgICAgICAgc2l6ZT0wLjgsCiAgICAgICAgICAgICAgYWxwaGE9MC43KSAgKyAgCiAgc2NhbGVfeF9sb2cxMCgpICsKICAgc2NhbGVfeV9sb2cxMCgpICArCiAgZmFjZXRfd3JhcCh+dHhfYmlvdHlwZSkgCmBgYAoKCiMjIFByZS1tUk5BIHZzIEV4b25pYyBsZW5ndGhzCgoKYGBge3IsIGZpZy53aWR0aD0yMH0KZ2dwbG90KHR4X2dlbmVfbWV0YSAlPiUKICAgICAgICAgZmlsdGVyKHR4X2Jpb3R5cGUgJWluJSB0eF9iaW90eXBlX3RhcmdldHMgJiBuZXhvbiE9MSksCiAgICAgICBhZXMoIHByZW1ybmFfbGVuLCBleG9uaWNfbGVuLCBjb2xvdXI9bmV4b24pKSArCiAgZ2VvbV9wb2ludCggc2l6ZT0wLjEsCiAgICAgICAgICAgICAgYWxwaGE9MC4zKSAgKyAgICAKICBnZW9tX2RlbnNpdHlfMmQoKSArICAKICBzY2FsZV94X2xvZzEwKCkgKwogICBzY2FsZV95X2xvZzEwKCkgKwogIGZhY2V0X3dyYXAofnR4X2Jpb3R5cGUpIApgYGAKCiMjIEV4b25pYyBDb3VudHMgdnMgRXhvbmljIGxlbmd0aHMKCgpgYGB7ciwgZmlnLndpZHRoPTIwfQpnZ3Bsb3QodHhfZ2VuZV9tZXRhICU+JQogICAgICAgICBmaWx0ZXIodHhfYmlvdHlwZSAlaW4lIHR4X2Jpb3R5cGVfdGFyZ2V0cyApLAogICAgICAgYWVzKCBuZXhvbiwgZXhvbmljX2xlbiwgY29sb3VyPXByZW1ybmFfbGVuKSkgKwogIGdlb21fcG9pbnQoIHNpemU9MC4xLAogICAgICAgICAgICAgIGFscGhhPTAuMykgICsgICAgCiAgc2NhbGVfeF9sb2cxMCgpICsKICAgc2NhbGVfeV9sb2cxMCgpICsKICBmYWNldF93cmFwKH50eF9iaW90eXBlKSAKYGBgCiMjIE51bWJlciBvZiB0cmFuc2NpcHRzIGJ5IGdlbmUKCmBgYHtyfQpjb3VudF90eF9ieV9nZW5lIDwtCiAgdHhfZ2VuZV9tZXRhICU+JQogIGNvdW50KGdlbmVfaWQsZ2VuZV9uYW1lLCBnZW5lX2Jpb3R5cGUpICU+JQogIGFycmFuZ2UoLW4pCmNvdW50X3R4X2J5X2dlbmUgCmBgYAoKCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTd9CmdncGxvdChjb3VudF90eF9ieV9nZW5lLCBhZXMobikpICsKICBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAwKSAgCmBgYApgYGB7cn0KdG9wX2dlbmVzIDwtIAogIGNvdW50X3R4X2J5X2dlbmUgJT4lCiAgc2xpY2UoMToyMCkgJT4lCiAgcHVsbChnZW5lX25hbWUpCnRvcF9nZW5lcwpgYGAKCgpgYGB7ciBmaWcuaGVpZ2h0PTE1fQpnZ3Bsb3QodHhfZ2VuZV9tZXRhICU+JSAKICAgICAgICAgZHBseXI6OmZpbHRlcihnZW5lX25hbWUlaW4lIHRvcF9nZW5lcykpKwogIGdlb21fcG9pbnQoIGFlcyhleG9uaWNfbGVuLCBpbnRyb25pY19sZW4sIGNvbG91cj1uZXhvbiA+PTEwKSkgKwogIGZhY2V0X3dyYXAoZ2VuZV9iaW90eXBlfmdlbmVfbmFtZSwgICBzY2FsZXMgPSAiZnJlZSIpCmBgYAoKCgoKYGBge3J9CnR4XzEwX2dlbmVzIDwtIAogIGNvdW50X3R4X2J5X2dlbmUgJT4lCiAgZmlsdGVyKG49PTEwKSAlPiUKICBzbGljZSgxOjIwKSAlPiUKICBwdWxsKGdlbmVfbmFtZSkKYGBgCgoKCmBgYHtyIGZpZy5oZWlnaHQ9MTV9CmdncGxvdCh0eF9nZW5lX21ldGEgJT4lIAogICAgICAgICBkcGx5cjo6ZmlsdGVyKGdlbmVfbmFtZSVpbiUgdHhfMTBfZ2VuZXMpKSsKICBnZW9tX3BvaW50KCBhZXMoZXhvbmljX2xlbiwgaW50cm9uaWNfbGVuLCBjb2xvdXI9bmV4b24gPj0xMCkpICsKICBmYWNldF93cmFwKH5nZW5lX25hbWUsICBzY2FsZXMgPSAiZnJlZSIpIAogIApgYGAKCgpgYGB7cn0Kc2luZ2xlX3RyYW5zY3JpcHRfZ2VuZXMgPC0KICBjb3VudF90eF9ieV9nZW5lICU+JSAKICBkcGx5cjo6ZmlsdGVyKG49PTEpICU+JSAKICBwdWxsKGdlbmVfbmFtZSkKbGVuZ3RoKHNpbmdsZV90cmFuc2NyaXB0X2dlbmVzKQpgYGAKCgoKYGBge3IgZmlnLmhlaWdodD04fQpnZ3Bsb3QodHhfZ2VuZV9tZXRhICAlPiUgCiAgICAgICAgIGRwbHlyOjpmaWx0ZXIoZ2VuZV9uYW1lJWluJSBzaW5nbGVfdHJhbnNjcmlwdF9nZW5lcyAmIGdlbmVfYmlvdHlwZSAlaW4lIGJpb3R5cGVfdGFyZ2V0cyApKSsKICBnZW9tX3BvaW50KCBhZXMoZXhvbmljX2xlbiwgaW50cm9uaWNfbGVuLCAgY29sb3VyPXBlcmNfZ2VuZV9nYyksCiAgICAgICAgICAgICAgc2l6ZT0wLjIsCiAgICAgICAgICAgICAgYWxwaGE9MC41KSAgKyAgCiAgc2NhbGVfeF9sb2cxMCgpICsKICAgc2NhbGVfeV9sb2cxMCgpICsKICBmYWNldF93cmFwKH50eF9iaW90eXBlKSAgKwogIHNjYWxlX2NvbG91cl9ncmFkaWVudDIobWlkcG9pbnQ9MTAsIG1pZCA9ICJ5ZWxsb3ciKQoKYGBgCgojIFNpbmdsZSBleG9uIHRyYW5zY3JpcHRzCgoKYGBge3J9CiAgdHhfZ2VuZV9tZXRhICU+JQogIGNvdW50KG5leG9uICkgJT4lCiAgYXJyYW5nZSgtbikKYGBgCgoKCgpgYGB7ciBmaWcuaGVpZ2h0PTEwfQpnZ3Bsb3QodHhfZ2VuZV9tZXRhICU+JSAKICAgICAgICAgZHBseXI6OmZpbHRlcih0eF9iaW90eXBlICVpbiUgdHhfYmlvdHlwZV90YXJnZXRzICYgbmV4b249PSAyKSkgKwogIGdlb21fcG9pbnQoIGFlcyhleG9uaWNfbGVuLCBpbnRyb25pY19sZW4sICBjb2xvdXI9cGVyY19nZW5lX2djKSwKICAgICAgICAgICAgICBzaXplPTAuMiwKICAgICAgICAgICAgICBhbHBoYT0wLjUpICArICAKICBzY2FsZV94X2xvZzEwKCkgKwogICBzY2FsZV95X2xvZzEwKCkgKwogIGZhY2V0X3dyYXAofnR4X2Jpb3R5cGUpICArCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50MihtaWRwb2ludD0xMCwgbWlkID0gInllbGxvdyIpCmBgYAoKCmBgYHtyIGZpZy5oZWlnaHQ9MTB9CmdncGxvdCh0eF9nZW5lX21ldGEgJT4lIAogICAgICAgICBkcGx5cjo6ZmlsdGVyKHR4X2Jpb3R5cGUgJWluJSB0eF9iaW90eXBlX3RhcmdldHMgJiBuZXhvbjwgMTAgJiBuZXhvbj4gMSkpICsKICBnZW9tX3BvaW50KCBhZXMoZXhvbmljX2xlbiwgaW50cm9uaWNfbGVuLCAgY29sb3VyPXBlcmNfZ2VuZV9nYyksCiAgICAgICAgICAgICAgc2l6ZT0wLjIsCiAgICAgICAgICAgICAgYWxwaGE9MC41KSAgKyAgCiAgc2NhbGVfeF9sb2cxMCgpICsKICAgc2NhbGVfeV9sb2cxMCgpICsKICBmYWNldF93cmFwKH50eF9iaW90eXBlKSAgKwogIHNjYWxlX2NvbG91cl9ncmFkaWVudDIobWlkcG9pbnQ9MTAsIG1pZCA9ICJ5ZWxsb3ciKQpgYGAKCmBgYHtyIGZpZy5oZWlnaHQ9MTB9CmdncGxvdCh0eF9nZW5lX21ldGEgJT4lIAogICAgICAgICBkcGx5cjo6ZmlsdGVyKHR4X2Jpb3R5cGUgJWluJSB0eF9iaW90eXBlX3RhcmdldHMgJiBuZXhvbj49IDEwKSkgKwogIGdlb21fcG9pbnQoIGFlcyhleG9uaWNfbGVuLCBpbnRyb25pY19sZW4sICBjb2xvdXI9cGVyY19nZW5lX2djKSwKICAgICAgICAgICAgICBzaXplPTAuMiwKICAgICAgICAgICAgICBhbHBoYT0wLjUpICArICAKICBzY2FsZV94X2xvZzEwKCkgKwogICBzY2FsZV95X2xvZzEwKCkgKwogIGZhY2V0X3dyYXAofnR4X2Jpb3R5cGUpICArCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50MihtaWRwb2ludD0xMCwgbWlkID0gInllbGxvdyIpCmBgYAoKCgoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBg